/**
 * @file main.c
 * @brief TCU应用主程序
 * @details 实现TCU设备应用的主入口，包括命令行参数解析、信号处理、守护进程等功能
 * @author 开发者
 * @date 2024
 * @version 1.0.0
 */

#include "tcu.h"
#include "../../log/logger.h"
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>

/**
 * @name 全局变量
 * @{
 */
static tcu_t g_tcu;                    /**< TCU设备实例 */
static volatile bool g_running = true; /**< 程序运行标志 */
/** @} */

/**
 * @brief 信号处理函数
 * @details 处理SIGINT和SIGTERM信号，优雅地关闭TCU设备
 * @param sig 信号编号
 */
static void signal_handler(int sig) {
    switch (sig) {
        case SIGINT:    // 1. 处理Ctrl+C信号
        case SIGTERM:   // 2. 处理终止信号
            LOG_INFO("接收到退出信号，正在关闭TCU设备...");
            g_running = false;      // 3. 设置运行标志为false
            break;
        default:
            break;
    }
}

/**
 * @brief 打印使用说明
 * @details 显示TCU应用的版本信息、命令行参数说明和使用示例
 * @param program_name 程序名称
 */
static void print_usage(const char *program_name) {
    printf("TCU设备应用 v%s\n", TCU_VERSION);        // 1. 显示版本信息
    printf("构建时间: %s %s\n", TCU_BUILD_DATE, TCU_BUILD_TIME);  // 2. 显示构建时间
    printf("\n");
    printf("用法: %s [选项]\n", program_name);        // 3. 显示用法说明
    printf("\n");
    printf("选项:\n");                                // 4. 显示选项列表
    printf("  -c, --config <dir>     指定配置目录 (默认: config)\n");
    printf("  -d, --daemon           以守护进程模式运行\n");
    printf("  -l, --log-level <level> 设置日志级别 (DEBUG, INFO, WARN, ERROR)\n");
    printf("  -h, --help             显示此帮助信息\n");
    printf("  -v, --version          显示版本信息\n");
    printf("\n");
    printf("示例:\n");                                // 5. 显示使用示例
    printf("  %s -c /etc/tcu/config\n", program_name);
    printf("  %s -d -l INFO\n", program_name);
    printf("\n");
}

// 打印版本信息
static void print_version(void) {
    printf("TCU设备应用 v%s\n", TCU_VERSION);
    printf("构建时间: %s %s\n", TCU_BUILD_DATE, TCU_BUILD_TIME);
    printf("Git提交: %s\n", TCU_VERSION);
    printf("\n");
}

/**
 * @brief TCU应用主函数
 * @details 程序入口点，负责命令行参数解析、日志系统初始化、TCU设备初始化和主循环
 * @param argc 命令行参数个数
 * @param argv 命令行参数数组
 * @return 程序退出状态码，0表示成功，非0表示失败
 */
int main(int argc, char *argv[]) {
    // 1. 初始化默认参数
    const char *config_dir = "config";
    bool daemon_mode = false;
    log_level_t log_level = LOG_LEVEL_DEBUG;  // 默认DEBUG级别便于调试
    
    // 2. 解析命令行参数
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--config") == 0) {
            if (i + 1 < argc) {
                config_dir = argv[++i];
            } else {
                fprintf(stderr, "错误: -c 选项需要指定配置目录\n");
                return 1;
            }
        } else if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--daemon") == 0) {
            daemon_mode = true;
        } else if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--log-level") == 0) {
            if (i + 1 < argc) {
                const char *level_str = argv[++i];
                if (strcmp(level_str, "DEBUG") == 0) {
                    log_level = LOG_LEVEL_DEBUG;
                } else if (strcmp(level_str, "INFO") == 0) {
                    log_level = LOG_LEVEL_INFO;
                } else if (strcmp(level_str, "WARN") == 0) {
                    log_level = LOG_LEVEL_WARN;
                } else if (strcmp(level_str, "ERROR") == 0) {
                    log_level = LOG_LEVEL_ERROR;
                } else {
                    fprintf(stderr, "错误: 无效的日志级别: %s\n", level_str);
                    return 1;
                }
            } else {
                fprintf(stderr, "错误: -l 选项需要指定日志级别\n");
                return 1;
            }
        } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
            print_usage(argv[0]);
            return 0;
        } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
            print_version();
            return 0;
        } else {
            fprintf(stderr, "错误: 未知选项: %s\n", argv[i]);
            print_usage(argv[0]);
            return 1;
        }
    }
    
    // 初始化日志系统
    log_config_t log_config = {
        .level = log_level,
        .target = LOG_TARGET_FILE,
        .file_path = "logs/tcu.log",
        .max_file_size = 10485760,  // 10MB
        .max_files = 5,
        .color_output = true,
        .timestamp = true,
        .thread_id = false,
        .file_line = true,
        .async_output = false,
        .buffer_size = 4096
    };
    
    if (logger_init(&log_config) != 0) {
        fprintf(stderr, "日志系统初始化失败\n");
        return 1;
    }
    
    LOG_INFO("TCU设备应用启动");
    LOG_INFO("版本: %s", TCU_VERSION);
    LOG_INFO("构建时间: %s %s", TCU_BUILD_DATE, TCU_BUILD_TIME);
    LOG_INFO("配置目录: %s", config_dir);
    LOG_INFO("日志级别: %d", log_level);
    
    // 设置信号处理
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGPIPE, SIG_IGN);
    
    // 守护进程模式
    if (daemon_mode) {
        LOG_INFO("以守护进程模式运行");
        if (daemon(0, 0) != 0) {
            LOG_ERROR("创建守护进程失败");
            return 1;
        }
    }
    
    // 初始化TCU设备
    if (tcu_init(&g_tcu, config_dir) != 0) {
        LOG_ERROR("TCU设备初始化失败");
        logger_cleanup();
        return 1;
    }
    
    // 启动TCU设备
    if (tcu_start(&g_tcu) != 0) {
        LOG_ERROR("TCU设备启动失败");
        tcu_cleanup(&g_tcu);
        logger_cleanup();
        return 1;
    }
    
    // 自动注册设备
    if (tcu_get_state(&g_tcu) == TCU_STATE_DISCONNECTED) {
        LOG_INFO("开始设备注册流程");
        
        // 首先尝试主动注册
        if (tcu_device_register(&g_tcu, "signup") == 0) {
            LOG_INFO("设备主动注册请求已发送");
        }
        
        // 等待一段时间后尝试普通注册
        sleep(2);
        if (tcu_device_register(&g_tcu, "register") == 0) {
            LOG_INFO("设备注册请求已发送");
        }
    }
    
    // 主循环
    LOG_INFO("TCU设备运行中，按Ctrl+C退出...");
    
    while (g_running) {
        // 检查设备状态
        tcu_state_t state = tcu_get_state(&g_tcu);
        
        switch (state) {
            case TCU_STATE_ERROR:
                LOG_ERROR("设备进入错误状态，尝试重新初始化");
                tcu_stop(&g_tcu);
                sleep(5);
                if (tcu_start(&g_tcu) == 0) {
                    LOG_INFO("设备重新启动成功");
                }
                break;
                
            case TCU_STATE_DISCONNECTED:
                // 尝试重连
                if (g_tcu.reconnect_count < g_tcu.data_config.max_reconnect_attempts) {
                    LOG_INFO("设备断开连接，尝试重连...");
                    g_tcu.reconnect_count++;
                    sleep(g_tcu.data_config.reconnect_interval);
                    // TODO: 实现重连逻辑
                } else {
                    LOG_ERROR("重连次数超过限制，停止重连");
                    g_running = false;
                }
                break;
                
            default:
                // 正常运行状态
                break;
        }
        
        sleep(1);
    }
    
    // 停止TCU设备
    LOG_INFO("正在停止TCU设备...");
    tcu_stop(&g_tcu);
    tcu_cleanup(&g_tcu);
    
    // 清理日志系统
    logger_cleanup();
    
    LOG_INFO("TCU设备应用退出");
    return 0;
}
